<template>
  <BasicModal
    v-bind="$attrs"
    @register="registerModal"
    destroyOnClose
    :title="title"
    :width="'50%'"
    :height="600"
    @ok="handleSubmit"
    @visible-change="handleAfterClose"
  >
    <div class="modal-content-container">
      <a-row :gutter="24" class="full-height">
        <!-- 左侧树结构 -->
        <a-col :span="showTree ? 8 : 0" class="tree-container">
          <a-input-search v-model:value="searchValue" placeholder="输入关键字搜索" class="mb-3" />
          <a-tree
            :expanded-keys="expandedKeys"
            :auto-expand-parent="autoExpandParent"
            :tree-data="filteredTreeData"
            :fieldNames="{ children: 'children', title: 'title', key: 'key' }"
            :checkable="!isDetail"
            v-model:checkedKeys="checkedKeys"
            @check="handleCheck"
            :checkStrictly="false"
            @expand="onExpand"
            :class="treeType === 'websocket' ? 'ws-tree' : ''"
          >
            <template #title="{ title, node, category }">
              <span
                :class="[
                  treeType === 'websocket' ? 'ws-node' : '',
                  treeType === 'websocket' && category === '字段类' ? 'ws-field' : '',
                  treeType === 'websocket' && category === 'SQL类' ? 'ws-sql' : '',
                ]"
              >
                <span v-if="title.indexOf(searchValue) > -1">
                  {{ title.substr(0, title.indexOf(searchValue)) }}
                  <span style="color: #f50">{{ searchValue }}</span>
                  {{ title.substr(title.indexOf(searchValue) + searchValue.length) }}
                </span>
                <span v-else>{{ title }}</span>
              </span>
            </template>
          </a-tree>
        </a-col>

        <!-- 右侧表单 -->
        <a-col :span="showTree ? 16 : 24" class="right-content">
          <BasicForm @register="registerForm" name="SysDataServiceForm">
            <template #needField="{ model, field }">
              <div style="display: flex; align-items: center; gap: 8px">
                <a-textarea v-model:value="model[field]" :auto-size="{ minRows: 3, maxRows: 6 }" style="flex: 1" />
                <a-button type="primary" style="height: 76px; padding: 0 16px" @click="handleSelectFields"> 验证sql </a-button>
              </div>
              <div class="data-info-container">
                <div class="data-info-card">
                  <div class="info-card-header">
                    <DatabaseOutlined class="info-icon" />
                    <span class="info-title">数据存储表</span>
                  </div>
                  <div class="info-content tags-container">
                    <span class="field-tag">user_info</span>
                    <span class="field-tag">order_list</span>
                    <span class="field-tag">product_catalog</span>
                    <span class="field-tag">system_config</span>
                    <span class="field-tag">data_archive</span>
                    <span class="field-tag">log_records</span>
                    <span class="field-tag">message_queue</span>
                  </div>
                </div>

                <!-- 数据结构表 -->
                <div class="data-info-card">
                  <div class="info-card-header">
                    <TableOutlined class="info-icon" />
                    <span class="info-title">数据结构表</span>
                  </div>
                  <div class="info-content tags-container">
                    <span class="field-tag">base_field</span>
                    <span class="field-tag">extend_field</span>
                    <span class="field-tag">relation_field</span>
                    <span class="field-tag">index_field</span>
                  </div>
                </div>

                <!-- JSON字段结构 -->
                <div class="data-info-card">
                  <div class="info-card-header">
                    <FileTextOutlined class="info-icon" />
                    <span class="info-title">JSON字段结构</span>
                  </div>
                  <div class="info-content tags-container">
                    <span class="field-tag">meta_info</span>
                    <span class="field-tag">ext_data</span>
                    <span class="field-tag">config_map</span>
                    <span class="field-tag">params_list</span>
                    <span class="field-tag">result_set</span>
                  </div>
                </div>
              </div>
            </template>
          </BasicForm>
          <template v-if="isDetail && formModel?.needField">
            <a-card title="关联资源" size="small" class="detail-list">
              <!-- 空状态提示 -->
              <template v-if="getAssociatedResources.length === 0">
                <div style="padding: 16px; text-align: center; color: #666"> 暂无关联资源 </div>
              </template>

              <!-- 列表内容 -->
              <a-list v-else :data-source="getAssociatedResources" :bordered="false" size="small">
                <template #renderItem="{ item }">
                  <a-list-item class="list-item">
                    <div class="item-content">{{ item }}</div>
                  </a-list-item>
                </template>
              </a-list>
            </a-card>
          </template>
          <template v-if="isDetail">
            <a-card title="接口信息" size="small" class="detail-list">
              <!-- 显示接口类型 -->
              <div class="info-item">
                <span class="info-label">接口类型：</span>
                <span class="info-value">{{ formModel.serviceCategory }}</span>
              </div>

              <!-- 显示接口名称 -->
              <div class="info-item">
                <span class="info-label">接口名称：</span>
                <span class="info-value">{{ formModel.interfaceName }}</span>
              </div>

              <!-- 根据接口类型显示服务地址 -->
              <div class="info-item" v-if="showServiceUrl">
                <span class="info-label">服务地址：</span>
                <span class="info-value">{{ serviceUrl }}</span>
              </div>

              <!-- 显示请求方式 -->
              <div class="info-item">
                <span class="info-label">请求方式：</span>
                <span class="info-value">{{ requestMethod }}</span>
              </div>

              <!-- 显示请求参数 -->
              <div class="info-item">
                <span class="info-label">请求参数：</span>
                <div class="info-value param-value">
                  <template v-if="isJsonParams">
                    <pre>{{ formattedParams }}</pre>
                  </template>
                  <template v-else>
                    {{ requestParams }}
                  </template>
                </div>
              </div>
            </a-card>
          </template>
          <!-- 标签展示区域 -->
          <template v-if="selectedTags.length > 0">
            <div class="biaoqian" :class="treeType === 'websocket' ? 'ws-tags' : 'device-tags'">
              <a-tag
                v-for="tag in selectedTags"
                :key="tag.id"
                :closable="!isDetail"
                @close="!isDetail && handleTagClose(tag.id)"
                style="margin-bottom: 8px; margin-right: 8px; padding: 4px 8px"
              >
                {{ tag.label }}
              </a-tag>
            </div>
          </template>
        </a-col>
      </a-row></div
    >
  </BasicModal>
</template>

<script lang="ts" setup>
  import { ref, computed, unref, onMounted, watch, nextTick } from 'vue';
  import { BasicModal, useModalInner } from '/@/components/Modal';
  import { BasicForm, useForm } from '/@/components/Form/index';
  import { formSchema } from '../SysDataService.data';
  import { saveOrUpdate, checkSql, list } from '../SysDataService.api'; // 修改：使用list接口获取表格数据
  import { getDeviceTree } from '../../shujuchuli/dataApplication.api';
  import { convertToTreeData } from '../../shujuchuli/treeUtils';
  import { render } from '/@/utils/common/renderUtils';

  // 全局勾选值池：存储所有树中用户勾选过的节点Key（不随树结构变化清空）
  const allVal = ref<string[]>([]);

  //当前树的所有节点Key集合（用于计算交集/补集，随树结构动态更新）
  const currentTreeAllKeys = ref<string[]>([]);
  // Emits声明
  const emit = defineEmits(['register', 'success']);
  const isUpdate = ref(true);
  const isDetail = ref(false);
  const showTree = ref(false);
  const formModel = ref<Recordable>({});

  // 搜索相关变量
  const searchValue = ref<string>('');
  const expandedKeys = ref<string[]>([]);
  const autoExpandParent = ref<boolean>(true);
  const dataList = ref<TreeDataItem[]>([]);
  const checkedKeys = ref<string[]>([]); // 存储选中节点keys

  // 新增：树类型相关状态
  const treeType = ref<'device' | 'websocket'>('device'); // 标记当前树类型
  const websocketTreeData = ref<TreeDataItem[]>([]); // WebSocket树数据

  // 接口信息相关计算属性
  const requestMethod = computed(() => {
    if (formModel.value?.interfaceName === '历史数据查询') {
      return 'POST';
    }
    return 'GET';
  });

  const showServiceUrl = computed(() => {
    return formModel.value?.serviceCategory === 'SQL类';
  });

  const serviceUrl = computed(() => {
    if (formModel.value?.serviceCategory === 'SQL类') {
      return '/xichang/sysDataService/queryBySql';
    }
    return '';
  });

  const requestParams = computed(() => {
    if (formModel.value?.interfaceName === '历史数据查询') {
      return {
        agreementName: 'udp', //协议名称
        deviceId: '1943205040248385537', //数据源id
        fieldKey: 'param6', //查询参数
        startTime: '2025-07-29 14:50:27', //开始时间
        endTime: '2025-07-29 15:55:27', //结束时间
      };
    } else if (formModel.value?.interfaceName === '坐标数据查询') {
      return 'id  //设备ID';
    }
    // 字段类和SQL类默认参数
    return 'id  //数据服务ID';
  });

  const isJsonParams = computed(() => {
    return formModel.value?.interfaceName === '历史数据查询';
  });

  const formattedParams = computed(() => {
    return JSON.stringify(requestParams.value, null, 2);
  });

  // 修改：类型切换处理，根据新的类型值（字段类1、SQL类3、WebSocket类4）控制树显示
  const handleTypeChange = async (value) => {
    // 显示树的条件：字段类(1)和WebSocket类(4)显示树，SQL类(3)不显示
    showTree.value = value === '1' || value === '4';

    if (!showTree.value) {
      checkedKeys.value = [];
      selectedTags.value = [];
      setFieldsValue({ needField: '' });
      return;
    }

    // 根据类型加载不同树数据
    if (value === '1') {
      treeType.value = 'device';
      await fetchDeviceTreeData();
    } else if (value === '4') {
      treeType.value = 'websocket';
      await fetchWebSocketTreeData();
    }

    // 重置勾选状态
    checkedKeys.value = [];
    selectedTags.value = [];
    setFieldsValue({ needField: '' });
  };

  import { useMessage } from '/@/hooks/web/useMessage';
  const { createMessage } = useMessage();

  // 验证SQL按钮点击处理
  const handleSelectFields = async () => {
    const values = await getFieldsValue();
    const sqlContent = values.needField;
    if (!sqlContent) {
      createMessage.warning('请输入SQL语句');
      return;
    }
    // 调用接口验证SQL
    await checkSql({ sql: sqlContent });
  };

  // 展开事件处理
  const onExpand = (keys: string[]) => {
    expandedKeys.value = keys;
    autoExpandParent.value = false;
  };

  // 表单配置
  const [registerForm, { setProps, resetFields, setFieldsValue, validate, scrollToField, getFieldsValue }] = useForm({
    labelWidth: 150,
    schemas: formSchema.map((schema) => {
      if (schema.field === 'serviceCategory') {
        return {
          ...schema,
          componentProps: (formModel) => {
            // 保留原有的componentProps配置
            const originalProps = schema.componentProps?.(formModel) || {};
            // 合并并添加onChange事件
            return {
              ...originalProps,
              onChange: handleTypeChange,
            };
          },
        };
      }
      return schema;
    }),
    showActionButtonGroup: false,
    baseColProps: { span: 24 },
  });

  // 表单赋值与模态框配置
  const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
    // 重置表单
    await resetFields();
    setModalProps({ confirmLoading: false, showCancelBtn: !!data?.showFooter, showOkBtn: !!data?.showFooter });
    isUpdate.value = !!data?.isUpdate;
    isDetail.value = !data?.showFooter;
    // 设置表单禁用状态
    setProps({ disabled: isDetail.value });

    if (unref(isUpdate)) {
      // 表单赋值
      const formData = { ...data.record };
      if (formData.serviceCategory !== undefined) {
        const dictValue = render.renderDict(formData.serviceCategory, 'service_category');
        formData.serviceCategory = dictValue?.children || formData.serviceCategory;
      }
      await setFieldsValue(formData);

      // 编辑模式：回显选中状态
      const categoryValue = data.record.serviceCategory; // 获取原始类型值(1/3/4)
      const needFieldValue = formData.needField || '';
      // 如果是需要显示树的类型且有数据，自动加载树并勾选节点
      if ((categoryValue === 1 || categoryValue === 4) && needFieldValue) {
        showTree.value = true;
        treeType.value = categoryValue === 1 ? 'device' : 'websocket';
        // 加载树数据
        if (categoryValue === 1) await fetchDeviceTreeData();
        else await fetchWebSocketTreeData();

        // 根据树类型确定有效层级
        const validLevel = treeType.value === 'device' ? 4 : 1;
        const treeSource = treeType.value === 'device' ? treeData.value : websocketTreeData.value;

        // 解析needFieldValue为节点Key，初始化allVal
        let echoKeys: string[] = [];
        if (categoryValue === 1) {
          // 设备树：解析needFieldValue为第四层节点Key
          echoKeys = needFieldValue
            .split(',')
            .filter(Boolean)
            .map((value) => {
              const parts = value.split('_');
              if (parts.length !== 5) return '';
              const [deviceMark, deviceCla, deviceCategory, id, field] = parts;
              const key = findDeviceNodeByFullPath(treeData.value, deviceMark, deviceCla, deviceCategory, id, field);
              // 验证找到的节点是否为第四层
              if (key) {
                const nodeInfo = findNodeByKey(key, treeSource);
                return nodeInfo?.node?.level === validLevel ? key : '';
              }
              return '';
            })
            .filter(Boolean);
        } else {
          // WebSocket树：直接拆分ID为第一层节点Key
          echoKeys = needFieldValue
            .split(',')
            .filter(Boolean)
            .filter((key) => {
              const nodeInfo = findNodeByKey(key, treeSource);
              return nodeInfo?.node?.level === validLevel;
            });
        }

        // 初始化全局勾选池和当前树勾选状态
        allVal.value = echoKeys;
        checkedKeys.value = getIntersection(currentTreeAllKeys.value, allVal.value).filter((key) => {
          const nodeInfo = findNodeByKey(key, treeSource);
          return nodeInfo?.node?.level === validLevel;
        });
        updateSelectedTags(); // 更新标签
      }
    }

    formModel.value = getFieldsValue();
    // 隐藏底部时禁用整个表单
    setProps({ disabled: !data?.showFooter });
  });

  // 字段类编辑回显处理（按完整层级匹配节点）
  const handleDeviceTypeEdit = async (needFieldValue: string) => {
    if (!needFieldValue) return;
    const values = needFieldValue.split(',').filter(Boolean);
    console.log(values, 'values');
    const nodeKeys: string[] = [];
    // 解析每条数据的完整层级信息（deviceMark_deviceCla_deviceCategory_id_field）
    for (const value of values) {
      const parts = value.split('_');
      // 严格校验格式（必须包含5个部分）
      if (parts.length !== 5) {
        console.warn('无效的needField格式:', value);
        continue;
      }

      const [targetDeviceMark, targetDeviceCla, targetDeviceCategory, targetId, targetField] = parts;
      console.log('解析目标节点信息:', {
        targetDeviceMark,
        targetDeviceCla,
        targetDeviceCategory,
        targetId,
        targetField,
      });
      // 递归查找：同时匹配父节点层级 + 目标字段
      const key = findDeviceNodeByFullPath(treeData.value, targetDeviceMark, targetDeviceCla, targetDeviceCategory, targetId, targetField);

      if (key) {
        nodeKeys.push(key);
      } else {
        console.warn(`未找到匹配节点: 设备标识=${targetDeviceMark}, 字段=${targetField}`);
      }
    }

    // 延迟设置，确保DOM已更新
    await nextTick();
    checkedKeys.value = nodeKeys;
    // 触发勾选事件，同步标签和表单
    handleCheck(nodeKeys, { node: null, checked: true });
  };

  // 辅助函数 - 按完整层级（设备标识→分类→ID→字段）查找节点
  const findDeviceNodeByFullPath = (
    treeData: TreeDataItem[],
    targetDeviceMark: string,
    targetDeviceCla: string,
    targetDeviceCategory: string,
    targetId: string,
    targetField: string
  ): string | null => {
    // 1. 第一层：匹配设备标识（deviceMark）
    for (const level1Node of treeData) {
      if (level1Node.rawData?.deviceMark !== targetDeviceMark) continue;
      if (!level1Node.children) continue;

      // 2. 第二层：匹配设备分类（deviceCla）
      for (const level2Node of level1Node.children) {
        if (level2Node.rawData?.deviceId !== targetDeviceCla) continue;
        if (!level2Node.children) continue;

        // 3. 第三层：匹配设备名称/ID（deviceCategory + id）
        for (const level3Node of level2Node.children) {
          const nodeCategory = level3Node.rawData?.deviceName || level3Node.rawData?.id;
          const nodeId = level3Node.rawData?.id;
          if (nodeCategory !== targetDeviceCategory || nodeId !== targetId) continue;
          if (!level3Node.children) continue;

          // 4. 第四层：匹配目标字段（field）
          for (const level4Node of level3Node.children) {
            if (level4Node.rawData?.field === targetField && level4Node.level === 4) {
              return level4Node.key as string; // 找到精准匹配的节点
            }
          }
        }
      }
    }

    return null; // 未找到匹配节点
  };

  // 新增：WebSocket类编辑回显处理
  const handleWebSocketTypeEdit = async (needFieldValue: string) => {
    if (!needFieldValue) return;
    const ids = needFieldValue.split(',').filter(Boolean);
    // 延迟设置，确保DOM已更新
    await nextTick();
    checkedKeys.value = ids;
    // 触发勾选事件，同步标签和表单
    handleCheck(ids, { node: null, checked: true });
  };

  // 新增：辅助函数 - 根据字段名查找设备树节点key
  const findDeviceNodeKeyByField = (treeData: TreeDataItem[], targetField: string): string | null => {
    for (const node of treeData) {
      // 只找第四层叶子节点
      if (node.level === 4 && node.rawData?.field === targetField) {
        return node.key as string;
      }
      // 递归查找子节点
      if (node.children && node.children.length > 0) {
        const foundKey = findDeviceNodeKeyByField(node.children, targetField);
        if (foundKey) return foundKey;
      }
    }
    return null;
  };
  // 设置标题
  const title = computed(() => (unref(isDetail) ? '详情' : !unref(isUpdate) ? '新增' : '编辑'));

  // 表单提交事件
  async function handleSubmit(v) {
    try {
      let values = await validate();
      // 提交前确保serviceCategory为数字
      if (values.serviceCategory !== undefined && values.serviceCategory !== null) {
        // 转换为数字（处理字符串形式的数字）
        const numericValue = render.textToDictValue(values.serviceCategory, 'service_category');
        // 验证转换结果是否有效
        if (!isNaN(numericValue)) {
          values.serviceCategory = numericValue;
        } else {
          throw new Error('接口类型格式错误，请重新选择');
        }
      }
      console.log(values.serviceCategory, 'values.serviceCategory');
      setModalProps({ confirmLoading: true });
      // 提交表单
      await saveOrUpdate(values, isUpdate.value);
      // 关闭弹窗
      closeModal();
      // 刷新列表
      emit('success');
    } catch ({ errorFields }) {
      if (errorFields) {
        const firstField = errorFields[0];
        if (firstField) {
          scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
        }
      }
      return Promise.reject(errorFields);
    } finally {
      setModalProps({ confirmLoading: false });
    }
  }

  // 树结构相关代码
  const treeData = ref([]);
  import type { TreeDataItem } from 'ant-design-vue/es/tree/Tree';

  // 获取父节点key
  const getParentKey = (key: string, tree: TreeDataItem[]): string | undefined => {
    for (let i = 0; i < tree.length; i++) {
      const node = tree[i];
      if (node.children) {
        if (node.children.some((item) => item.key === key)) {
          return node.key;
        }
        const parentKey = getParentKey(key, node.children);
        if (parentKey) return parentKey;
      }
    }
  };
  // 监听搜索值变化
  watch(searchValue, (value) => {
    // 1. 获取当前树的数据源（设备树/WebSocket树，根据treeType切换）
    const sourceData = treeType.value === 'device' ? treeData.value : websocketTreeData.value;
    // 2. 找到所有包含搜索关键词的节点的「父节点Key」，用于自动展开父节点
    const expanded = dataList.value
      .map((item) => {
        if (item.title!.indexOf(value) > -1) {
          // 找到当前节点的父节点Key（确保搜索到的节点父级自动展开）
          return getParentKey(item.key as string, sourceData || []);
        }
        return null;
      })
      .filter((item, i, self) => item && self.indexOf(item) === i);
    // 3. 更新展开的节点Key，让包含关键词的节点父级自动展开
    expandedKeys.value = expanded as string[];
    autoExpandParent.value = true;
  });
  // 新增：收集过滤后树数据的所有节点Key
  const collectFilteredTreeKeys = (filteredData: TreeDataItem[]) => {
    const keys: string[] = [];
    const traverse = (nodes: TreeDataItem[]) => {
      nodes.forEach((node) => {
        keys.push(node.key as string);
        if (node.children && node.children.length) {
          traverse(node.children);
        }
      });
    };
    traverse(filteredData);
    return keys;
  };

  // 生成扁平数据列表
  const generateList = (data: TreeDataItem[]) => {
    dataList.value = []; // 清空现有列表
    const buildList = (nodes: TreeDataItem[]) => {
      for (let i = 0; i < nodes.length; i++) {
        const node = nodes[i];
        dataList.value.push({ key: node.key, title: node.title });
        if (node.children) {
          buildList(node.children);
        }
      }
    };
    buildList(data); // 执行递归处理
    // 生成列表后，自动计算当前树应显示的勾选状态（allVal与当前树Key的交集）
    updateSelectedTags();
  };

  // 过滤树数据
  const filteredTreeData = computed(() => {
    // 1. 获取当前树的原始数据源（设备树/WebSocket树）
    const sourceData = treeType.value === 'device' ? treeData.value : websocketTreeData.value;
    // 2. 若搜索值为空，直接返回原始数据（树显示全部节点）
    if (!searchValue.value) return sourceData;
    // 3. 递归过滤树节点：只保留「标题包含搜索值」或「子节点包含搜索值」的节点
    const filterTree = (data: TreeDataItem[]): TreeDataItem[] => {
      return data
        .filter((item) => {
          // 节点自身标题包含搜索值 → 保留
          const match = item.title!.includes(searchValue.value);
          // 若节点有子节点，递归过滤子节点 → 子节点有匹配的也保留当前节点
          if (item.children) {
            const childMatch = filterTree(item.children);
            return match || childMatch.length > 0;
          }
          return match;
        })
        .map((item) => ({
          ...item,
          // 递归处理子节点，确保子节点也符合过滤条件
          children: item.children ? filterTree(item.children) : [],
        }));
    };
    // 4. 返回过滤后的树数据，树组件会自动重新渲染
    return filterTree(sourceData || []);
  });
  // 监听过滤后的树数据变化，同步更新 currentTreeAllKeys
  watch(filteredTreeData, (newFilteredData) => {
    currentTreeAllKeys.value = collectFilteredTreeKeys(newFilteredData);
    // 同时更新勾选状态（只保留当前显示节点中被勾选的部分）
    checkedKeys.value = getIntersection(allVal.value, currentTreeAllKeys.value);
    console.log(currentTreeAllKeys.value, 'currentTreeAllKeys.value');
    updateSelectedTags(); // 同步标签显示
  });
  // 获取设备树数据
  const fetchDeviceTreeData = async () => {
    try {
      const res = await getDeviceTree();
      if (!res || !res.deviceOneList) throw new Error('设备树数据格式不正确');
      treeData.value = convertToTreeData(res.deviceOneList);
      generateList(treeData.value); // 生成列表时会自动同步currentTreeAllKeys和checkedKeys
    } catch (err) {
      console.error('获取设备树失败:', err);
      createMessage.error('获取设备树失败，请重试');
      treeData.value = [];
      dataList.value = [];
      currentTreeAllKeys.value = [];
      checkedKeys.value = [];
    }
  };

  // 修改：从list接口获取WebSocket树所需的接口数据
  const fetchWebSocketTreeData = async () => {
    try {
      const tableData = await list();
      const filteredData = tableData.records.filter((item) => item.serviceCategory === 1 || item.serviceCategory === 3);
      websocketTreeData.value = filteredData.map((item) => {
        const categoryName = item.serviceCategory === 1 ? '字段类' : 'SQL类';
        return {
          key: item.id,
          title: `${item.id || '未命名接口'}（${item.interfaceName}）`,
          category: categoryName,
          level: 1,
          isLeaf: true,
          rawData: { interfaceId: item.id, interfaceName: item.interfaceName, category: categoryName },
        };
      });
      generateList(websocketTreeData.value); // 生成列表时会自动同步currentTreeAllKeys和checkedKeys
      if (websocketTreeData.value.length === 0) createMessage.warning('未找到可用的字段类或SQL类接口');
    } catch (err) {
      createMessage.error('获取接口列表失败', err);
      websocketTreeData.value = [];
      dataList.value = [];
      currentTreeAllKeys.value = [];
      checkedKeys.value = [];
    }
  };
  // 2. 集合运算工具函数（复用）
  const getIntersection = (arr1: string[], arr2: string[]) => arr1.filter((key) => arr2.includes(key)); //交集
  const getUnion = (arr1: string[], arr2: string[]) => [...new Set([...arr1, ...arr2])]; //求并集
  const getComplement = (arr1: string[], arr2: string[]) => arr1.filter((key) => !arr2.includes(key)); //求补集

  // 树节点选择处理
  const handleCheck = (checkedKeysValue: string[], { node, checked }) => {
    // 根据树类型动态判断允许勾选的层级
    const getValidLevel = () => {
      if (treeType.value === 'device') return 4; // 设备树只允许第四层
      if (treeType.value === 'websocket') return 1; // WebSocket树只允许第一层
      return -1; // 其他情况不允许勾选
    };
    const validLevel = getValidLevel();
    console.log(node, 'validLevel');
    // 1. 基础过滤：仅保留当前树中存在的节点 + 符合层级要求的节点
    const validCheckedKeys = checkedKeysValue
      .filter((key) => currentTreeAllKeys.value.includes(key)) // 过滤当前树不存在的节点
      .filter((key) => {
        // 根据树类型获取对应数据源
        const treeSource = treeType.value === 'device' ? treeData.value : websocketTreeData.value;
        const nodeInfo = findNodeByKey(key, treeSource);
        return nodeInfo?.node?.level === validLevel; // 只保留符合层级要求的节点
      });
    const getCurrentValidNodes = () => {
      const treeSource = treeType.value === 'device' ? filteredTreeData.value : websocketTreeData.value;
      const validNodes: string[] = [];

      // 递归收集当前树中符合层级要求的节点
      const collectValidNodes = (nodes: TreeDataItem[]) => {
        nodes.forEach((node) => {
          if (node.level === validLevel) {
            validNodes.push(node.key as string);
          }
          if (node.children && node.children.length) {
            collectValidNodes(node.children);
          }
        });
      };
      collectValidNodes(treeSource);
      return validNodes;
    };
    // 3. 更新全局allVal（仅包含符合层级的节点）
    if (checked) {
      allVal.value = getUnion(allVal.value, validCheckedKeys);
    } else {
      console.log(currentTreeAllKeys, 'currentTreeAllKeys');
      const currentTreeComplement = getComplement(allVal.value, currentTreeAllKeys.value);
      allVal.value = getUnion(currentTreeComplement, validCheckedKeys);
    }

    // 4. 回显当前树的勾选状态（仍需过滤符合层级的节点）
    checkedKeys.value = getIntersection(currentTreeAllKeys.value, allVal.value).filter((key) => {
      const treeSource = treeType.value === 'device' ? treeData.value : websocketTreeData.value;
      const nodeInfo = findNodeByKey(key, treeSource);
      return nodeInfo?.node?.level === validLevel;
    });

    // 5. 更新标签和表单值
    updateSelectedTags();
    syncNeedFieldValue();
  };

  // 辅助函数1：基于allVal更新selectedTags（全局勾选节点对应的标签）
  const updateSelectedTags = () => {
    // 根据树类型确定有效层级
    const validLevel = treeType.value === 'device' ? 4 : 1;
    const treeSource = treeType.value === 'device' ? treeData.value : websocketTreeData.value;

    selectedTags.value = allVal.value
      .map((key) => {
        const result = findNodeByKey(key, treeSource);
        // 仅保留符合当前树类型层级要求的节点标签
        if (result?.node?.level === validLevel) {
          return {
            id: key,
            label: treeType.value === 'device' ? result.node.rawData?.field || key : result.node.title || key,
          };
        }
        return null;
      })
      .filter(Boolean); // 过滤不符合层级的节点
  };

  // 辅助函数2：基于allVal同步表单needField字段值
  const syncNeedFieldValue = () => {
    let needFieldValue = '';
    const validLevel = treeType.value === 'device' ? 4 : 1;
    const treeSource = treeType.value === 'device' ? treeData.value : websocketTreeData.value;

    if (treeType.value === 'device') {
      // 设备树：格式化第四层节点
      needFieldValue = allVal.value
        .map((key) => {
          const result = findNodeByKey(key, treeSource);
          if (result?.node?.level === validLevel) {
            const parentNodes = result.path.slice(0, -1);
            const deviceMark = parentNodes[0]?.rawData?.deviceMark;
            const deviceCla = parentNodes[1]?.rawData?.deviceId;
            const deviceCategory = parentNodes[2]?.rawData?.deviceName || parentNodes[2]?.rawData?.id;
            const id = parentNodes[2]?.rawData?.id;
            const field = result.node.rawData.field;
            return `${deviceMark}_${deviceCla}_${deviceCategory}_${id}_${field}`;
          }
          return null;
        })
        .filter(Boolean)
        .join(',');
    } else if (treeType.value === 'websocket') {
      // WebSocket树：直接拼接第一层节点ID
      needFieldValue = allVal.value
        .filter((key) => {
          const result = findNodeByKey(key, treeSource);
          return result?.node?.level === validLevel;
        })
        .join(',');
    }
    setFieldsValue({ needField: needFieldValue });
  };

  // 节点查找函数
  function findNodeByKey(key: string, treeData, path = []): any {
    for (const node of treeData) {
      const currentPath = [...path, node];
      if (node.key === key) return { node, path: currentPath };
      if (node.children) {
        const found = findNodeByKey(key, node.children, currentPath);
        if (found) return found;
      }
    }
  }

  // 标签关闭处理
  const selectedTags = ref<Array<{ id: string; label: string }>>([]);
  const handleTagClose = (closedKey: string) => {
    // 从allVal中删除关闭的Key
    allVal.value = allVal.value.filter((key) => key !== closedKey);
    // 回显当前树的勾选状态
    checkedKeys.value = getIntersection(currentTreeAllKeys.value, allVal.value);
    // 更新标签和表单
    updateSelectedTags();
    syncNeedFieldValue();
  };

  // 简化后的关联资源展示逻辑：直接返回分割后的数组
  const getAssociatedResources = computed(() => {
    const needField = formModel.value?.needField || '';
    if (!needField) return [];
    // 仅将字符串按逗号分割并过滤空值，不做额外处理
    return needField.split(',').filter(Boolean);
  });

  // 弹窗关闭后处理
  const handleAfterClose = () => {
    checkedKeys.value = [];
    selectedTags.value = [];
    showTree.value = false;
    searchValue.value = '';
  };

  // 初始加载
  onMounted(() => {
    nextTick(() => {
      // 可以在这里根据初始类型加载对应树数据
    });
  });
</script>

<style lang="less" scoped>
    /** 时间和数字输入框样式 */
    :deep(.ant-input-number) {
      width: 100%;
    }

    :deep(.ant-calendar-picker) {
      width: 100%;
    }

    .detail-list {
      margin-top: 16px;
      :deep(.ant-card-body) {
        padding: 0;
      }
      .list-item {
        padding: 8px 16px;
        border-bottom: 1px solid #f0f0f0;
        &:last-child {
          border-bottom: none;
        }
        .item-content {
          font-family: monospace;
          color: #314659;
        }
      }
    }

    // 标签样式
    .biaoqian {
      margin-top: 16px;
      border-radius: 4px;
      padding: 10px 10px;
      box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
      transition: all 0.2s ease;
    }

    // WebSocket标签样式
    .biaoqian.ws-tags {
      border: 1px solid #fa8c16;
      background-color: #fff7e6;
      :deep(.ant-tag) {
        border-color: #fa8c16;
        background: #fff7e6;
        color: #fa8c16;
        &:hover {
          border-color: #faad14;
          background: #fff1cc;
        }
      }
    }

    // 设备树标签样式
    .biaoqian.device-tags {
      border: 1px solid #99ccff;
      background-color: #f0f7ff;
      :deep(.ant-tag) {
        border-color: #1890ff;
        background: #e6f7ff;
        color: #1890ff;
      }
    }

    .biaoqian:hover {
      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    }
   .modal-content-container {
      height: calc(100% - 48px); // 减去标题栏高度
      overflow: hidden; // 防止整体滚动
    }

    .full-height {
      height: 100%;
      display: flex;
    }
    .tree-container {
      box-shadow: 4px 0 6px -4px rgba(0, 0, 0, 0.1);
     position: relative;
     height: 100%; // 填满父容器高度
     overflow-y: auto; // 仅左侧树出现滚动条
     padding: 8px;
     box-sizing: border-box; // 确保padding不影响整体高度
    }
   // 右侧内容样式
   .right-content {
     height: 100%;
     overflow: hidden; // 禁止右侧滚动
     padding: 0 8px;
     box-sizing: border-box;
   }
    // 接口信息样式
    .info-item {
      padding: 8px 16px;
      border-bottom: 1px solid #f0f0f0;
      &:last-child {
        border-bottom: none;
      }
    }
  // 树节点样式优化（可选）
   :deep(.ant-tree) {
     padding-bottom: 20px; // 底部留出空间，避免最后一个节点被遮挡
   }

   :deep(.ant-tree-node) {
     padding: 2px 0; // 增加节点间距，提升可读性
   }
   // 自定义滚动条样式
   .tree-container::-webkit-scrollbar {
     width: 6px;
     height: 6px;
   }

   .tree-container::-webkit-scrollbar-track {
     background: #f1f1f1;
     border-radius: 3px;
   }

   .tree-container::-webkit-scrollbar-thumb {
     background: #ccc;
     border-radius: 3px;
   }

   .tree-container::-webkit-scrollbar-thumb:hover {
     background: #aaa;
   }
    .info-label {
      display: inline-block;
      width: 100px;s
      color: #666;
      font-weight: 500;
    }

    .info-value {
      color: #333;
    }

    .param-value pre {
      background: #f5f5f5;
      padding: 10px;
      border-radius: 4px;
      overflow-x: auto;
      margin: 0;
      font-family: monospace;
    }

    // WebSocket树节点样式
    :deep(.ws-tree) {
      .ws-node {
        &.ws-field {
          color: #52c41a;
        }
        &.ws-sql {
          color: #1890ff;
        }
      }
    }






    .tags-container {
      display: flex;
      flex-wrap: wrap; // 自动换行
      gap: 8px; // 标签间距
      margin-top: 4px;
    }

    // 单个字段标签样式
    .field-tag {
      background: #f0f7ff;
      color: #1890ff;
      padding: 2px 8px;
      border-radius: 4px;
      font-size: 12px;
      white-space: nowrap; // 防止字段名换行
      border: 1px solid #e6f7ff;
      transition: all 0.2s;

      &:hover {
        background: #e6f7ff;
        transform: translateY(-1px);
      }
    }

    // 保持之前的其他样式
    .data-info-container {
      // display: flex;
      gap: 12px;
      width: 100%;
      flex-wrap: wrap;
      margin-top:20px;
    }

    .data-info-card {
      // flex: 1;
      margin-bottom: 12px;
      min-width: 250px;
      background: #fafafa;
      border-radius: 8px;
      padding: 14px 16px;
      border: 1px solid #f0f0f0;
      transition: all 0.3s ease;

      &:hover {
        transform: translateY(-2px);
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
        border-color: #e0e0e0;
      }
    }

    .info-card-header {
      display: flex;
      align-items: center;
      margin-bottom: 8px;
    }

    .info-icon {
      color: #1890ff;
      font-size: 16px;
      margin-right: 8px;
    }

    .info-title {
      font-size: 14px;
      font-weight: 500;
      color: #333;
    }
</style>
